package com.ken.apollo.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * 图片处理服务
 * 
 * @author Ken
 * @since 2024-01-01
 */
@Service
@Slf4j
public class ImageProcessingService {

    @Value("${upload.path}")
    private String uploadPath;

    /**
     * 调整图片分辨率
     * 
     * @param filename 原文件名
     * @param width 目标宽度
     * @param height 目标高度
     * @param quality 质量(0.1-1.0)
     * @return 新文件名
     */
    public String resizeImage(String filename, int width, int height, float quality) {
        try {
            File originalFile = new File(uploadPath, filename);
            if (!originalFile.exists()) {
                throw new RuntimeException("原文件不存在: " + filename);
            }

            // 读取原图片
            BufferedImage originalImage = ImageIO.read(originalFile);
            if (originalImage == null) {
                throw new RuntimeException("无法读取图片文件: " + filename);
            }

            // 计算新尺寸（保持宽高比）
            int[] newDimensions = calculateDimensions(originalImage.getWidth(), 
                                                    originalImage.getHeight(), 
                                                    width, height);

            // 创建高质量的缩放图片
            BufferedImage resizedImage = createHighQualityResizedImage(originalImage, 
                                                                     newDimensions[0], 
                                                                     newDimensions[1]);

            // 生成新文件名
            String newFilename = generateNewFilename(filename, width, height);
            File newFile = new File(uploadPath, newFilename);

            // 保存图片
            String formatName = getImageFormat(filename);
            boolean saved = ImageIO.write(resizedImage, formatName, newFile);
            
            if (!saved) {
                throw new RuntimeException("保存图片失败");
            }

            log.info("图片处理成功: {} -> {}, 尺寸: {}x{}", filename, newFilename, 
                    newDimensions[0], newDimensions[1]);

            return newFilename;

        } catch (IOException e) {
            log.error("图片处理失败: {}", filename, e);
            throw new RuntimeException("图片处理失败: " + e.getMessage());
        }
    }

    /**
     * 创建高质量的缩放图片
     */
    private BufferedImage createHighQualityResizedImage(BufferedImage original, int width, int height) {
        // 创建高质量的图片对象
        BufferedImage resized = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        
        Graphics2D graphics = resized.createGraphics();
        try {
            // 设置高质量渲染选项
            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);

            // 绘制缩放后的图片
            graphics.drawImage(original, 0, 0, width, height, null);
            
        } finally {
            graphics.dispose();
        }
        
        return resized;
    }

    /**
     * 计算保持宽高比的新尺寸
     */
    private int[] calculateDimensions(int originalWidth, int originalHeight, int targetWidth, int targetHeight) {
        double aspectRatio = (double) originalWidth / originalHeight;
        
        int newWidth = targetWidth;
        int newHeight = (int) (targetWidth / aspectRatio);
        
        if (newHeight > targetHeight) {
            newHeight = targetHeight;
            newWidth = (int) (targetHeight * aspectRatio);
        }
        
        return new int[]{newWidth, newHeight};
    }

    /**
     * 生成新文件名
     */
    private String generateNewFilename(String originalFilename, int width, int height) {
        String extension = getFileExtension(originalFilename);
        String nameWithoutExt = originalFilename.substring(0, originalFilename.lastIndexOf('.'));
        return nameWithoutExt + "_" + width + "x" + height + "." + extension;
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        int lastDotIndex = filename.lastIndexOf('.');
        return lastDotIndex > 0 ? filename.substring(lastDotIndex + 1).toLowerCase() : "jpg";
    }

    /**
     * 获取图片格式
     */
    private String getImageFormat(String filename) {
        String extension = getFileExtension(filename);
        return switch (extension) {
            case "png" -> "PNG";
            case "gif" -> "GIF";
            case "bmp" -> "BMP";
            default -> "JPEG";
        };
    }

    /**
     * 获取图片信息
     */
    public ImageInfo getImageInfo(String filename) {
        try {
            File file = new File(uploadPath, filename);
            if (!file.exists()) {
                return null;
            }

            BufferedImage image = ImageIO.read(file);
            if (image == null) {
                return null;
            }

            return new ImageInfo(image.getWidth(), image.getHeight(), file.length());

        } catch (IOException e) {
            log.error("获取图片信息失败: {}", filename, e);
            return null;
        }
    }

    /**
     * 图片信息类
     */
    public static class ImageInfo {
        private final int width;
        private final int height;
        private final long fileSize;

        public ImageInfo(int width, int height, long fileSize) {
            this.width = width;
            this.height = height;
            this.fileSize = fileSize;
        }

        public int getWidth() { return width; }
        public int getHeight() { return height; }
        public long getFileSize() { return fileSize; }
    }
}